package com.yonyou.ucf.mdf.app.mobile.module;

import com.yonyou.diwork.exception.BusinessException;
import com.yonyou.iuap.context.InvocationInfoProxy;
import com.yonyou.workbench.util.YkjConfig;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.isvrequest.ISVRequest;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.isvrequest.ISVRequestBody;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;


@Slf4j
@Component
@RequiredArgsConstructor
public class YkjInvocationComponent {

  private final ISVRequest isvRequest;

  private YkjConfig config;

  public YkjConfig getConfig() {
    return this.config;
  }

  public void setConfig(YkjConfig config) {
    this.config = config;
  }

  public String get(String uri, Map<String, String> parameters) throws BusinessException {
    try {
      if (parameters == null) {
        parameters = new HashMap();
      }

      String signUrl = this.buildGetUrl(uri, (String)null, (Map)parameters);
      log.info("sign后的地址：" + signUrl);
      ISVRequestBody isvRequestBody = new ISVRequestBody();
      isvRequestBody.setUrl(signUrl);
      isvRequestBody.setRequestMethod("GET");
      String s = isvRequest.doRequest(InvocationInfoProxy.getTenantid(),isvRequestBody);
      log.info("返回结果 :{}" + s);
      JSONObject jsonObject = JSONObject.fromObject(s);
      if (jsonObject.containsKey("code")) {
        if (jsonObject.getInt("code") == 0) {
          return jsonObject.get("data").toString();
        } else {
          throw new BusinessException("友空间返回数据格式异常,详细信息为：" + jsonObject.get("msg"));
        }
      } else if (StringUtils.isBlank(s)) {
        log.error("友空间返回结果为null或者''");
        throw new BusinessException("友空间返回结果为null或者''");
      } else {
        log.error("友空间返回结果异常:{}", s);
        throw new BusinessException("友空间返回结果异常:" + s);
      }
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      throw new BusinessException(e);
    }
  }

  private String buildGetUrl(String path, String localApiVersion, Map<String, String> parameters) throws Exception {
    log.info("请求方式：get");
    StringBuilder url = this.buildSign(path, localApiVersion, parameters, this.config.getInapiHost());
    if (!parameters.isEmpty()) {
      Iterator iter = parameters.keySet().iterator();

      while(iter.hasNext()) {
        String key = (String)iter.next();
        String value = (String)parameters.get(key);

        try {
          url.append("&").append(key).append("=").append(URLDecoder.decode(value, "utf-8"));
        } catch (UnsupportedEncodingException e) {
          log.error("拼接in-api get 请求url报错，iapi url为：{}, 参数包含：{}", new Object[]{path, parameters, e});
          throw new Exception("in-api签名报错", e);
        }
      }
    }

    return url.toString();
  }


  private StringBuilder buildSign(String path, String localApiVersion, Map<String, String> parameters, String inapiHost) throws Exception {
    long timestamp = (new Date()).getTime();
    String version = StringUtils.isEmpty(localApiVersion) ? this.config.getApiVersion() : localApiVersion;
    Map<String, String> sortMap = new TreeMap();
    if (!parameters.isEmpty()) {
      sortMap.putAll(parameters);
    }

    sortMap.put("token", this.config.getToken());
    sortMap.put("timestamp", "" + timestamp);
    sortMap.put("v", version);
    sortMap.put("agent_id", this.config.getAgent_id());
    StringBuilder signStr = new StringBuilder(path);
    Iterator iter = sortMap.keySet().iterator();

    String sign;
    while(iter.hasNext()) {
      sign = (String)iter.next();
      String value = (String)sortMap.get(sign);
      signStr.append(sign).append("=").append(value).append("&");
    }

    signStr.deleteCharAt(signStr.length() - 1);
    signStr.append(this.config.getSalt());
    log.info("请求ip：" + inapiHost);
    log.info("请求接口：" + path);
    log.info("请求参数：" + parameters);
    log.info("加密前：" + signStr);
    sign = DigestUtils.md5Hex(signStr.toString());
    log.info("加密后：" + sign);
    StringBuilder url = new StringBuilder(inapiHost);
    url.append(path).append("?");
    url.append("token=").append(this.config.getToken());
    url.append("&timestamp=").append(timestamp);
    url.append("&v=").append(version);
    url.append("&sign=").append(sign);
    url.append("&agent_id=").append(this.config.getAgent_id());
    return url;
  }
}
